﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Paros.BLL;
using Paros.Domain;
namespace Paros.Win
{
    enum NodeState
    { 
        Editing,
        None
    }

    public partial class CategoryForm : ToolboxBaseForm
    {
        CategoryMgr categoryMgr;
        TreeNode rootNode;
        NodeState nodeState = NodeState.None;
        public CategoryForm()
        {
            InitializeComponent();
            categoryMgr = new CategoryMgr();
        }

        private void RefreshParent(TreeNode parentNode)
        {
            if (parentNode != null)
            { 
                CategoryItem parentCategory = parentNode.Tag as CategoryItem;
                if (parentCategory != null)
                {
                    parentNode.Collapse();
                    DataTable table = categoryMgr.GetCategoriesByParentId(parentCategory.CategoryID);
                    if (parentNode.GetNodeCount(true) > 0)
                    {
                        foreach (TreeNode node in parentNode.Nodes)
                        {
                            node.Remove();
                        }
                    }
                    DataRow[] parentRow = table.Select("[ID]=" + parentCategory.CategoryID);
                    if(parentRow != null && parentRow.Length > 0 )
                        PopulateChildrenNode(parentRow[0], parentNode);

                    parentNode.Expand();
                }
            }
        }

        private void CategoryForm_Load(object sender, EventArgs e)
        {
            LoadData();
            contextMenuStrip1.Renderer = new Office2007Renderer.Office2007Renderer();
        }

        private void LoadData()
        {
            tvCategory.Nodes.Clear();
            DataTable table = categoryMgr.GetAllCategories();
            foreach (DataRow row in table.Rows)
            {
                if (row.IsNull("Parent"))
                {
                    TreeNode parentNode = PopulateNode(row);
                    PopulateChildrenNode(row, parentNode);
                }
            
            }
            rootNode = tvCategory.Nodes[0];
            rootNode.ExpandAll();
        }

        private TreeNode PopulateNode(DataRow row)
        {
            CategoryItem item = categoryMgr.GetItem(row);
            TreeNode node = new TreeNode();
            node.Text = item.CategoryName;
            node.Name = item.CategoryID.ToString();
            node.Tag = item;
            tvCategory.Nodes.Add(node);
            return node;
        }

        private void PopulateChildrenNode(DataRow parentRow, TreeNode parentNode)
        {
            foreach (DataRow row in parentRow.GetChildRows("parent-child"))
            {
                TreeNode node = new TreeNode();
                CategoryItem item = categoryMgr.GetItem(row);
                node.Text = string.Format("{0}({1})", item.CategoryName, item.Count);
                node.Tag = item;
                node.Name = item.CategoryID.ToString();
                parentNode.Nodes.Add(node);
                PopulateChildrenNode(row, node);
            }
        }

        private void addEntryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ((mainForm)this.ParentForm).NewEntry();
        }

        private void tvCategory_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            // make sure right click can set current node selected
            tvCategory.SelectedNode = e.Node;
            
        }

        private void tvCategory_AfterSelect(object sender, TreeViewEventArgs e)
        {
            // reset all context menues - [RESOLVE: if user right-click on root node, all others node can't be del/renamed util right click on them]
            foreach (ToolStripItem item in contextMenuStrip1.Items)
            {
                item.Enabled = true;
            }

            // store current user selected category to memory
            CategoryItem category = e.Node.Tag as CategoryItem;
            UserPreferences.SelectedCategory = category;

            // active entries list reload data
            ((mainForm)this.TopLevelControl).OnCategoryChanged();
        }

        private void tvCategory_BeforeLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            //disable user active root node edit mode
            if (e.Node == rootNode || nodeState != NodeState.Editing)
                e.CancelEdit = true;

        }
 

        private void renameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode node = tvCategory.SelectedNode;
            if (node != null && rootNode != node)
            {
                int pos = node.Text.IndexOf("(");
                if (pos > 0)
                    node.Text = node.Text.Substring(0, pos);
                nodeState = NodeState.Editing;
                node.BeginEdit();
            }
        }

        private void addCategoryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode node = tvCategory.SelectedNode;
            if (node != null)
            {
                TreeNode newNode = node.Nodes.Add("new node");
                tvCategory.SelectedNode = newNode;
                nodeState = NodeState.Editing;
                newNode.BeginEdit();
            }
        }

        public void RefreshCategoryCount(string key)
        {
            TreeNode[] nodes = tvCategory.Nodes.Find(key, true);
            if (nodes != null && nodes.Length > 0)
            {
                CategoryItem newItem = categoryMgr.GetItem(Convert.ToInt32(key));
                nodes[0].Tag = newItem;
                UpdateNode(nodes[0], nodes[0].Text);
            }
        }

        private void UpdateNodeParent(TreeNode node, TreeNode parent)
        {
            categoryMgr.UpdateCategory(Convert.ToInt32(node.Name), Convert.ToInt32(parent.Name));
        }

        private void UpdateNode(TreeNode node, string newText)
        {
            CategoryItem item = node.Tag as CategoryItem;
            if (item != null)
            {
                int posBegin = newText.LastIndexOf('(');
                if (posBegin > -1)
                {
                    newText = newText.Substring(0, posBegin);
                }
                node.Text = string.Format("{0}({1})", newText, item.Count);
                node.Name = item.CategoryID.ToString();
   
            }
            node.EndEdit(false);
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode node = tvCategory.SelectedNode;
            if (node != null && rootNode != node)
            {
                if (MessageBox.Show("All descendant nodes will be deleted, are you sure to delete category ["+ node.Text +"]?", Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    node.Remove();
                    categoryMgr.DeleteCategory(node, true);
                }
            }
        }

        private void expandAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode node = tvCategory.SelectedNode;
            if (node != null)
            {
                node.ExpandAll();
            }
        }

        private void collapseAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode node = tvCategory.SelectedNode;
            if (node != null)
            {
                node.Collapse();
            }
        }

        private void tvCategory_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            if (e.Node != null)
            {
                if (e.Label != null && e.Label.IndexOf('(') > -1)
                {
                    Utils.MessageHelper.ShowError("Special characters are not allowed.");
                    return;
                }

                int res = categoryMgr.UpdateCategory(e.Node, e.Label);
                //refresh new node
                CategoryItem item = categoryMgr.GetItem(categoryMgr.GetCategory(res));
                e.Node.Tag = item;

                //you can't update node text in this event by default
                e.CancelEdit = true;
                if(e.Label == null)
                    UpdateNode(e.Node, e.Node.Text);
                else
                    UpdateNode(e.Node, e.Label);
                nodeState = NodeState.None;
                
            }
        }

        private void refreshToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LoadData();
        }

        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {
            ContextMenuStrip menu = sender as ContextMenuStrip;
            if (menu != null)
            {
                TreeView tree = ((TreeView)menu.SourceControl) as TreeView;
                if (tree != null)
                {
                    TreeNode node = tree.SelectedNode;
                    if (node == tree.TopNode)
                    {
                        renameToolStripMenuItem.Enabled = false;
                        deleteToolStripMenuItem.Enabled = false;
                    }
                    else
                    {
                        foreach (ToolStripItem item in contextMenuStrip1.Items)
                        {
                            item.Enabled = true;
                        }
                    }

                }
                
            }

        }

        private void tvCategory_ItemDrag(object sender, ItemDragEventArgs e)
        {
            DoDragDrop(e.Item, DragDropEffects.Move);
        }

        private void tvCategory_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(TreeNode)))
            {
                e.Effect = DragDropEffects.Move;
            }
            else
                e.Effect = DragDropEffects.None;
        }

        private void tvCategory_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(TreeNode)))
            {
                TreeNode sourceNode = e.Data.GetData(typeof(TreeNode)) as TreeNode;
                TreeNode targetNode = tvCategory.SelectedNode;
                if (sourceNode != null && targetNode != null && sourceNode != targetNode)
                {
                    if (Utils.MessageHelper.ShowConfirmation("Are you sure to move nodes here?") == DialogResult.Yes)
                    {
                        sourceNode.Remove();
                        targetNode.Nodes.Add(sourceNode);
                        UpdateNodeParent(sourceNode, targetNode);
                        sourceNode.EnsureVisible();
                    }
                }
            }
            e.Effect = DragDropEffects.None;
        }

        private void tvCategory_DragOver(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(TreeNode)))
            {
                TreeNode sourceNode = e.Data.GetData(typeof(TreeNode)) as TreeNode;
                Point point = tvCategory.PointToClient(new Point(e.X, e.Y));
                TreeNode targetNode = tvCategory.GetNodeAt(point);
                TreeNode tempNode = targetNode;
                while (tempNode != null)
                {
                    if (tempNode == sourceNode)
                        return;

                    tempNode = tempNode.Parent;
                }
                tvCategory.SelectedNode = targetNode;
            }
        }

       
        
    }
}
